package com.xyt.imei.core.api;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.web.PageableDefault;
import org.springframework.data.web.SortDefault;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.google.gson.Gson;
import com.luminary.common.framework.core.auth.ValidateToken;
import com.luminary.common.framework.core.model.Pagination;
import com.luminary.common.framework.core.model.SimpleResponse;
import com.luminary.component.util.common.BeanMapUtils;
import com.xyt.imei.core.meta.CacheKey;
import com.xyt.imei.core.meta.DefaultValue;
import com.xyt.imei.core.meta.PageConstants;
import com.xyt.imei.core.meta.RoleEnum;
import com.xyt.imei.core.meta.ServerInfo;
import com.xyt.imei.core.model.dto.UserDTO;
import com.xyt.imei.core.model.dto.UserPasswordDTO;
import com.xyt.imei.core.model.dto.UserQueryDTO;
import com.xyt.imei.core.model.dto.UsernamePasswordDTO;
import com.xyt.imei.core.model.po.User;
import com.xyt.imei.core.service.UserService;
import com.xyt.imei.core.util.TokenUtil;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
@RequestMapping("user")
public class UserApi {
	
	@Autowired
	private PasswordEncoder passwordEncoder;
	
	@Autowired
	private RedisTemplate<String, String> redisTemplate;
	
	@Autowired
	private TokenUtil tokenUtil;
	
	@Autowired
	private UserService userService;
	
	@ValidateToken(roles = {RoleEnum.ADMIN_VALUE + "", RoleEnum.CMCC_VALUE + "", RoleEnum.BRANCH_VALUE + ""})
	@GetMapping("/branch/page")
	public SimpleResponse queryBranch(
			@Valid UserQueryDTO userQueryDTO,
			@PageableDefault(page=PageConstants.DEFAULT_PAGE_NO,size=PageConstants.DEFAULT_PAGE_SIZE)
			@SortDefault.SortDefaults({
				@SortDefault(sort = "create_date", direction = Direction.DESC)
			}) Pageable pageable,
			HttpServletResponse response) throws Exception {
		log.info("userQueryDTO:" + userQueryDTO + ",pageable:" + pageable.toString());
		
		Pagination<User> pagination = new Pagination<User>(pageable);
		
		Map<String, Object> params = new HashMap<String, Object>();
		params = BeanMapUtils.beanToMap(userQueryDTO);
		params.put("username", userQueryDTO.getUsername());
		params.put("phone", userQueryDTO.getPhone());
		pagination.setParams(params, pageable);
		
		return SimpleResponse.success(userService.findByPage(pagination), response);
	}
	
	@PostMapping("/login")
	public SimpleResponse login(
			@Valid UsernamePasswordDTO usernamePasswordDTO,
			HttpServletResponse response
			) throws Exception {
		log.info("username:" + usernamePasswordDTO.getUsername());
		
		String code = redisTemplate.opsForValue().get(ServerInfo.CACHE_PREFIX + "_" + CacheKey.VALIDATE_IMAGE_CODE + usernamePasswordDTO.getValidateImageCode().toLowerCase());
		
		if(code == null)
			return SimpleResponse.failed("验证码错误，重新输入", response);
		
		if(!usernamePasswordDTO.getValidateImageCode().equalsIgnoreCase(code.trim()))
			return SimpleResponse.failed("验证码错误，重新输入", response);
		
		SimpleResponse result = ServerInfo.validate(passwordEncoder, redisTemplate, usernamePasswordDTO, response);
		if(result != null) {
			return result;
		}
				
		User user = userService.findByUsername(usernamePasswordDTO.getUsername());
		
		if(user == null)
			return SimpleResponse.failed("用户不存在", response);
		
		if(!passwordEncoder.matches(usernamePasswordDTO.getPassword(), user.getPassword()))
			return SimpleResponse.failed("密码错误", response);
		
		Gson gson = new Gson();
		String token = passwordEncoder.encode(user.getUserId() + user.getUsername());
		redisTemplate.opsForValue().set(ServerInfo.CACHE_PREFIX + "_" + CacheKey.TOKEN + "_" + token, gson.toJson(user), 8, TimeUnit.HOURS);
		
		return SimpleResponse.success(token + "," + user.getRole(), response);
	}
	
	@PostMapping("/login/extra")
	public SimpleResponse loginExtra(
			@Valid UsernamePasswordDTO usernamePasswordDTO,
			HttpServletResponse response
			) throws Exception {
		
		log.info("username:" + usernamePasswordDTO.getUsername());
		
		String code = redisTemplate.opsForValue().get(ServerInfo.CACHE_PREFIX + "_" + CacheKey.VALIDATE_IMAGE_CODE + usernamePasswordDTO.getValidateImageCode().toLowerCase());
		
		if(code == null)
			return SimpleResponse.failed("验证码错误，重新输入", response);
		
		if(!usernamePasswordDTO.getValidateImageCode().equalsIgnoreCase(code.trim()))
			return SimpleResponse.failed("验证码错误，重新输入", response);
		
		SimpleResponse result = ServerInfo.validate(passwordEncoder, redisTemplate, usernamePasswordDTO, response);
		if(result != null) {
			return result;
		}
				
		User user = userService.findByUsername(usernamePasswordDTO.getUsername());
		
		if(user.getExtraFlag() == null || user.getExtraFlag().intValue() != 1) 
			return SimpleResponse.failed("您没有权限", response);
		
		if(user == null)
			return SimpleResponse.failed("用户不存在", response);
		
		if(!passwordEncoder.matches(usernamePasswordDTO.getPassword(), user.getPassword()))
			return SimpleResponse.failed("密码错误", response);
		
		Gson gson = new Gson();
		String token = passwordEncoder.encode(user.getUserId() + user.getUsername());
		redisTemplate.opsForValue().set(ServerInfo.CACHE_PREFIX + "_" + CacheKey.TOKEN + "_" + token, gson.toJson(user), 8, TimeUnit.HOURS);
		
		return SimpleResponse.success(token + "," + user.getRole(), response);
		
	}
	
	@PostMapping("/loginOut")
	public SimpleResponse loginOut(
			HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		String token = tokenUtil.getToken();
		redisTemplate.delete(ServerInfo.CACHE_PREFIX + "_" + CacheKey.TOKEN + "_" + token);
		return SimpleResponse.success("注销成功", response);
	}
	
	@ValidateToken(roles = {RoleEnum.ADMIN_VALUE + "", RoleEnum.CMCC_VALUE + ""})
	@PutMapping("/branch")
	public SimpleResponse createBranch(
			@Valid UserDTO userDTO,
			HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		log.info("userDTO:" + userDTO.toString());
		
		User user = tokenUtil.getUser();
		
		User newUser = new User();
		BeanUtils.copyProperties(userDTO, newUser);
		newUser.setPassword(passwordEncoder.encode(DefaultValue.DEFAULT_PASSWORD));
		newUser.setRole(RoleEnum.BRANCH_VALUE);
		newUser.setCreateBy(user.getUserId());
		newUser.setCreateDate(new Date());
		userService.add(newUser);
		
		return SimpleResponse.success("新增成功", response);
	}
	
	@ValidateToken(roles = {RoleEnum.ADMIN_VALUE + "", RoleEnum.CMCC_VALUE + ""})
	@PutMapping("/{userid}")
	public SimpleResponse delete(
			@PathVariable("userid") int userid,
			@Valid UserDTO userDTO,
			HttpServletResponse response)  throws Exception  {
		log.info("userDTO:" + userDTO.toString());
		
		User user = tokenUtil.getUser();
		User modifyUser = new User();
		modifyUser.setUserId(userid);
		modifyUser.setUsername(userDTO.getUsername());
		modifyUser.setUpdateBy(user.getUserId());
		modifyUser.setUpdateDate(new Date());
		userService.modifyByPrimaryKeySelective(modifyUser);
		
		return SimpleResponse.success("修改用户信息成功", response);
	}
	
	@ValidateToken(roles = {RoleEnum.ADMIN_VALUE + "", RoleEnum.CMCC_VALUE + ""})
	@PutMapping("/password/{userid}")
	public SimpleResponse initPassword(
			@PathVariable("userid") int userid,
			HttpServletRequest request,
			HttpServletResponse response
			) throws Exception {
		log.info("userid:" + userid);
		
		User user = tokenUtil.getUser();
		
		User modifyUser = new User();
		modifyUser.setUserId(userid);
		modifyUser.setPassword(passwordEncoder.encode(DefaultValue.DEFAULT_PASSWORD));
		modifyUser.setUpdateBy(user.getUserId());
		modifyUser.setUpdateDate(new Date());
		userService.modifyByPrimaryKeySelective(modifyUser);
		
		return SimpleResponse.success("初始化密码成功", response);
	}
	
	@ValidateToken(roles = {RoleEnum.ADMIN_VALUE + "", RoleEnum.CMCC_VALUE + "", RoleEnum.BRANCH_VALUE + ""})
	@PutMapping("/password")
	public SimpleResponse updatePassword(
			@Valid UserPasswordDTO userPasswordDTO,
			HttpServletRequest request,
			HttpServletResponse response
			) throws Exception {
		User user = tokenUtil.getUser();
		
		log.info("userId:" + user.getUserId());
		
		User modifyUser = new User();
		modifyUser.setUserId(user.getUserId());
		modifyUser.setPassword(passwordEncoder.encode(userPasswordDTO.getPassword()));
		modifyUser.setUpdateBy(user.getUserId());
		modifyUser.setUpdateDate(new Date());
		
		userService.modifyByPrimaryKeySelective(modifyUser);
		
		return SimpleResponse.success("修改密码成功", response);
	}
	
}
